package com.example.ercmssystem2.service.impl;

import com.example.ercmssystem2.entity.Event;
import com.example.ercmssystem2.entity.TaskReport;
import com.example.ercmssystem2.entity.TaskReportPhoto;
import com.example.ercmssystem2.repository.EventRepository;
import com.example.ercmssystem2.repository.TaskReportRepository;
import com.example.ercmssystem2.repository.TaskReportPhotoRepository;
import com.example.ercmssystem2.service.TaskReportService;
import com.example.ercmssystem2.service.EventService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class TaskReportServiceImpl implements TaskReportService {

    @Autowired
    private TaskReportRepository taskReportRepository;
    
    @Autowired
    private EventRepository eventRepository;
    
    @Autowired
    private EventService eventService;
    
    @Autowired
    private TaskReportPhotoRepository taskReportPhotoRepository;
    
    @Value("${app.upload.path:uploads}")
    private String uploadPath;

    @Override
    public TaskReport createCompletionReport(Long eventId, String content, Long reportedBy) {
        Event event = eventRepository.findById(eventId).orElse(null);
        if (event == null) {
            throw new RuntimeException("事件不存在");
        }
        
        // 检查是否已存在完成报告
        List<TaskReport> existingReports = taskReportRepository.findByEventIdOrderByReportTimeDesc(eventId);
        if (!existingReports.isEmpty()) {
            throw new RuntimeException("该事件已提交过完成报告，不能重复提交");
        }
        
        TaskReport report = new TaskReport();
        report.setEvent(event);
        report.setContent(content);
        report.setReportTime(LocalDateTime.now());
        report.setReportedBy(reportedBy);
        TaskReport savedReport = taskReportRepository.save(report);
        
        // 自动更新事件状态为完成
        try {
            eventService.completeEvent(eventId, reportedBy, content);
        } catch (Exception e) {
            // 如果事件状态更新失败，记录日志但不影响报告保存
            System.err.println("事件状态更新失败: " + e.getMessage());
        }
        
        return savedReport;
    }

    @Override
    public TaskReport createCompletionReportWithPhotos(Long eventId, String content, Long reportedBy, List<MultipartFile> photos, List<String> descriptions) {
        // 先创建报告
        TaskReport report = createCompletionReport(eventId, content, reportedBy);
        
        // 如果有照片，则上传照片
        if (photos != null && !photos.isEmpty()) {
            for (int i = 0; i < photos.size(); i++) {
                MultipartFile photo = photos.get(i);
                String description = (descriptions != null && i < descriptions.size()) ? descriptions.get(i) : "";
                if (photo != null && !photo.isEmpty()) {
                    uploadPhoto(report.getId(), photo, description, reportedBy);
                }
            }
        }
        
        return report;
    }

    @Override
    public TaskReport findById(Long id) {
        return taskReportRepository.findById(id).orElse(null);
    }

    @Override
    public List<TaskReport> findByEventId(Long eventId) {
        return taskReportRepository.findByEventIdOrderByReportTimeDesc(eventId);
    }

    @Override
    public TaskReport findLatestCompletionReport(Long eventId) {
        List<TaskReport> reports = taskReportRepository.findByEventIdOrderByReportTimeDesc(eventId);
        return reports.isEmpty() ? null : reports.get(0);
    }

    @Override
    public TaskReport saveReport(TaskReport report) {
        return taskReportRepository.save(report);
    }

    @Override
    public void deleteReport(Long id) {
        taskReportRepository.deleteById(id);
    }

    @Override
    public List<TaskReport> findByReportedBy(Long reportedBy) {
        return taskReportRepository.findByReportedByOrderByReportTimeDesc(reportedBy);
    }

    @Override
    public List<TaskReport> findByReportTimeBetween(LocalDateTime start, LocalDateTime end) {
        return taskReportRepository.findByReportTimeBetweenOrderByReportTimeDesc(start, end);
    }

    @Override
    public long countByEventId(Long eventId) {
        return taskReportRepository.countByEventId(eventId);
    }

    @Override
    public Map<String, Object> getReportStatistics(Long eventId) {
        Map<String, Object> statistics = new HashMap<>();
        long totalReports = taskReportRepository.countByEventId(eventId);
        statistics.put("totalReports", totalReports);
        return statistics;
    }
    
    @Override
    public TaskReport updateReport(Long reportId, String content, Long reportedBy) {
        TaskReport report = taskReportRepository.findById(reportId).orElse(null);
        if (report == null) {
            throw new RuntimeException("报告不存在");
        }
        
        // 只有报告创建者可以修改
        if (!report.getReportedBy().equals(reportedBy)) {
            throw new RuntimeException("只有报告创建者可以修改报告");
        }
        
        report.setContent(content);
        report.setReportTime(LocalDateTime.now()); // 更新修改时间
        return taskReportRepository.save(report);
    }

    @Override
    public TaskReport updateReportWithPhotos(Long reportId, String content, Long reportedBy, List<MultipartFile> photos, List<String> descriptions) {
        // 先更新报告内容
        TaskReport report = updateReport(reportId, content, reportedBy);
        
        // 如果有新照片，则上传照片
        if (photos != null && !photos.isEmpty()) {
            for (int i = 0; i < photos.size(); i++) {
                MultipartFile photo = photos.get(i);
                String description = (descriptions != null && i < descriptions.size()) ? descriptions.get(i) : "";
                if (photo != null && !photo.isEmpty()) {
                    uploadPhoto(reportId, photo, description, reportedBy);
                }
            }
        }
        
        return report;
    }

    @Override
    public TaskReportPhoto uploadPhoto(Long reportId, MultipartFile file, String description, Long uploadedBy) {
        TaskReport report = taskReportRepository.findById(reportId).orElse(null);
        if (report == null) {
            throw new RuntimeException("报告不存在");
        }
        
        // 验证文件类型
        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("image/")) {
            throw new RuntimeException("只能上传图片文件");
        }
        
        // 验证文件大小（限制为10MB）
        if (file.getSize() > 10 * 1024 * 1024) {
            throw new RuntimeException("图片文件大小不能超过10MB");
        }
        
        try {
            // 创建上传目录
            String datePath = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
            String uploadDir = uploadPath + "/task-reports/" + datePath;
            Path dirPath = Paths.get(uploadDir);
            if (!Files.exists(dirPath)) {
                Files.createDirectories(dirPath);
            }
            
            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String extension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String filename = UUID.randomUUID().toString() + extension;
            String filePath = uploadDir + "/" + filename;
            
            // 保存文件
            Path targetPath = Paths.get(filePath);
            Files.copy(file.getInputStream(), targetPath);
            
            // 保存照片信息到数据库
            TaskReportPhoto photo = new TaskReportPhoto();
            photo.setTaskReport(report);
            photo.setFilePath(filePath);
            photo.setFileName(originalFilename != null ? originalFilename : filename);
            photo.setFileSize(file.getSize());
            photo.setContentType(contentType);
            photo.setDescription(description);
            photo.setUploadTime(LocalDateTime.now());
            photo.setUploadedBy(uploadedBy);
            
            return taskReportPhotoRepository.save(photo);
            
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败: " + e.getMessage());
        }
    }

    @Override
    public List<TaskReportPhoto> getReportPhotos(Long reportId) {
        return taskReportPhotoRepository.findByTaskReportIdOrderByUploadTimeAsc(reportId);
    }

    @Override
    public TaskReportPhoto getPhotoById(Long photoId) {
        return taskReportPhotoRepository.findById(photoId).orElse(null);
    }

    @Override
    public void deletePhoto(Long photoId, Long userId) {
        TaskReportPhoto photo = taskReportPhotoRepository.findById(photoId).orElse(null);
        if (photo == null) {
            throw new RuntimeException("照片不存在");
        }
        
        // 只有上传者或报告创建者可以删除照片
        if (!photo.getUploadedBy().equals(userId) && !photo.getTaskReport().getReportedBy().equals(userId)) {
            throw new RuntimeException("无权删除此照片");
        }
        
        try {
            // 删除文件
            Path filePath = Paths.get(photo.getFilePath());
            if (Files.exists(filePath)) {
                Files.delete(filePath);
            }
            
            // 删除数据库记录
            taskReportPhotoRepository.delete(photo);
            
        } catch (IOException e) {
            throw new RuntimeException("删除文件失败: " + e.getMessage());
        }
    }

    @Override
    public List<TaskReport> findReportsWithFilters(Long eventId, Long reporterId, LocalDateTime start, LocalDateTime end, int page, int size) {
        // 这里需要根据条件构建查询
        // 由于JPA Repository的限制，我们可能需要使用@Query注解或Criteria API
        // 暂时返回所有报告，后续可以优化
        return taskReportRepository.findAll();
    }
    
    @Override
    public long countReportsWithFilters(Long eventId, Long reporterId, LocalDateTime start, LocalDateTime end) {
        // 暂时返回总数，后续可以优化
        return taskReportRepository.count();
    }
    
    @Override
    public Map<String, Object> getReportStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 总报告数
        long totalReports = taskReportRepository.count();
        statistics.put("totalReports", totalReports);
        
        // 今日报告数
        LocalDateTime todayStart = LocalDateTime.now().toLocalDate().atStartOfDay();
        LocalDateTime todayEnd = LocalDateTime.now().toLocalDate().atTime(23, 59, 59);
        long todayReports = taskReportRepository.countByReportTimeBetween(todayStart, todayEnd);
        statistics.put("todayReports", todayReports);
        
        // 本周报告数
        LocalDateTime weekStart = LocalDateTime.now().toLocalDate().minusDays(LocalDateTime.now().getDayOfWeek().getValue() - 1).atStartOfDay();
        long weekReports = taskReportRepository.countByReportTimeBetween(weekStart, todayEnd);
        statistics.put("weekReports", weekReports);
        
        // 本月报告数
        LocalDateTime monthStart = LocalDateTime.now().toLocalDate().withDayOfMonth(1).atStartOfDay();
        long monthReports = taskReportRepository.countByReportTimeBetween(monthStart, todayEnd);
        statistics.put("monthReports", monthReports);
        
        return statistics;
    }
} 